﻿using UnityEngine;
using System.Collections;

namespace net {
	public class NetCtrl : MonoBehaviour {
		
		// 配置数据
		Config cfg = new Config ();
		SpeedCfg speedcfg = new SpeedCfg();
		public NetPlayerState state;
		public int reverseFactor = 1;
		// 方向 1234 ~ 上下左右
		
		// 炮弹初始位置偏移量
		float bulletOffset = 0.75f;
		
		Vector2 UP; 
		Vector2 DOWN; 
		Vector2 LEFT; 
		Vector2 RIGHT; 
		
		Vector3 pos;
		
		// Use this for initialization
		void Start () {
			UP= new Vector2(0, 1*reverseFactor);
			DOWN= new Vector2(0, -1*reverseFactor);
			LEFT= new Vector2(-1*reverseFactor, 0);
			RIGHT= new Vector2(1*reverseFactor, 0);
			state = GetComponent<NetPlayerState>();
		}
		
		// Update is called once per frame
		void Update () {
			pos = transform.position;
			
			// 死了就不能动了
			if (!state.isAlive) {
				return;
			}
			if(state.hasInertia){
				autoRun();
				return;
			}
			
			//------ WASD移动
			if (Input.GetKey (KeyCode.A)) {
				// 向左移动
				if (canMove(Common.LEFT*reverseFactor)) {
					transform.position = new Vector3(pos.x - Time.deltaTime * state.speed*reverseFactor, pos.y, pos.z);
				}
				// 转向
				transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90*reverseFactor));
				state.direction = Common.LEFT*reverseFactor;
			}
			else if (Input.GetKey (KeyCode.D)) {
				// 向右移动
				if (canMove(Common.RIGHT*reverseFactor)) {
					transform.position = new Vector3(pos.x + Time.deltaTime * state.speed*reverseFactor, pos.y, pos.z);
				}
				// 转向
				transform.rotation = Quaternion.Euler(new Vector3(0, 0, 270*reverseFactor));
				state.direction = Common.RIGHT*reverseFactor;
			}
			else if (Input.GetKey (KeyCode.W)) {
				// 向上移动
				if (canMove(Common.UP*reverseFactor)) {
					transform.position = new Vector3(pos.x, pos.y + Time.deltaTime * state.speed*reverseFactor, pos.z);
				}
				// 转向
				//!!! 角度逆时针为正
				float x = reverseFactor==-1?180:0;
				transform.rotation = Quaternion.Euler(new Vector3(0, 0,x));
				state.direction = Common.UP*reverseFactor;
			}
			else if (Input.GetKey (KeyCode.S)) {
				// 向下移动
				if (canMove(Common.DOWN*reverseFactor)) {
					transform.position = new Vector3(pos.x, pos.y - Time.deltaTime * state.speed*reverseFactor, pos.z);
				}
				// 转向
				float x = reverseFactor==-1?0:180;
				transform.rotation = Quaternion.Euler(new Vector3(0, 0, x));
				state.direction = Common.DOWN*reverseFactor;
			}
			//------ end WASD移动
			
			//------ J开火
			if (Input.GetKeyDown (KeyCode.J)) {
				Vector3 bulletPos = Vector3.zero;
				
				if(!state.readyToFire){
					return;
				}
				
				if (state.direction == Common.UP*reverseFactor) {
					bulletPos = new Vector3(pos.x, pos.y + bulletOffset*reverseFactor, pos.z);
				}
				else if (state.direction == Common.DOWN*reverseFactor) {
					bulletPos = new Vector3(pos.x, pos.y - bulletOffset*reverseFactor, pos.z);
				}
				else if (state.direction == Common.LEFT*reverseFactor) {
					bulletPos = new Vector3(pos.x - bulletOffset*reverseFactor, pos.y, pos.z);
				}
				else if (state.direction == Common.RIGHT*reverseFactor) {
					bulletPos = new Vector3(pos.x + bulletOffset*reverseFactor, pos.y, pos.z);
				}
			//	TODO 用网络的生成
				GetComponent<NetBullet>().NewBomb(state.direction, bulletPos,gameObject,true);
				state.readyToFire = false;
				// print("has fired");
				// biu
				AudioSource audioSource = GetComponent<AudioSource> ();
				audioSource.clip = Resources.Load ("mp3/biu") as AudioClip;
				audioSource.Play ();
			}
			//------ end J开火
		}
		
		public bool canMove (int direction) {
			float rayOffset = 0.2f;
			float distance = 0.1f;
			
			bool res = true;
			GameObject[] objs = null;
			
			if (direction == Common.LEFT) {
				objs = objsDetect(new Vector2(pos.x - 1, pos.y + 1 - rayOffset),
				                  new Vector2(pos.x - 1, pos.y - 1 + rayOffset),
				                  LEFT,
				                  distance
				                  );
			}
			else if (direction == Common.RIGHT) {
				objs = objsDetect(new Vector2(pos.x + 1, pos.y + 1 - rayOffset),
				                  new Vector2(pos.x + 1, pos.y - 1 + rayOffset),
				                  RIGHT,
				                  distance
				                  );
			}
			else if (direction == Common.UP) {
				objs = objsDetect(new Vector2(pos.x - 1 + rayOffset, pos.y + 1),
				                  new Vector2(pos.x + 1 - rayOffset, pos.y + 1),
				                  UP,
				                  distance
				                  );
			}
			else if (direction == Common.DOWN) {
				objs = objsDetect(new Vector2(pos.x - 1 + rayOffset, pos.y - 1),
				                  new Vector2(pos.x + 1 - rayOffset, pos.y - 1),
				                  DOWN,
				                  distance
				                  );
			}
			
			for (int i = 0; i < objs.Length; i++) {
				if (!canPass(objs[i])) {
					res = false;
				}
			}
			
			float preSpeed = state.speed;
			state.speed = speedcfg.getSpeed(objs);
			//从雪地出去了
			if(preSpeed>state.speed &&(speedcfg.getSpeed("snow")== preSpeed)){ 
				state.hasInertia = true;
				state.preTime = Time.time;
			}
			
			return res;
		}
		
		bool canPass(GameObject obj) {
			string objName;
			bool res = true;
			
			if (obj != null) {
				objName = Common.getObjName (obj);
				res = cfg.canTankPass (objName);
			}
			
			return res;
		}
		
		GameObject[] objsDetect(Vector2 start, Vector2 end, Vector2 direction, float distance) {
			GameObject[] objs = new GameObject[7];
			
			// start
			objs[0] = rayDetect(start, direction, distance);
			// end
			objs[1] = rayDetect(end, direction, distance);
			
			// 中间
			if (LEFT.Equals (direction) || RIGHT.Equals(direction)) {
				objs[2] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2), direction, distance);
				objs[3] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 - 0.3f), direction, distance);
				objs[4] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 - 0.6f), direction, distance);
				objs[5] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 + 0.3f), direction, distance);
				objs[6] = rayDetect(new Vector2(start.x, (start.y + end.y) / 2 + 0.6f), direction, distance);
			}
			else if (UP.Equals (direction) || DOWN.Equals(direction)) {
				objs[2] = rayDetect(new Vector2((start.x + end.x) / 2, start.y), direction, distance);
				objs[3] = rayDetect(new Vector2((start.x + end.x) / 2 - 0.3f, start.y), direction, distance);
				objs[4] = rayDetect(new Vector2((start.x + end.x) / 2 - 0.6f, start.y), direction, distance);
				objs[5] = rayDetect(new Vector2((start.x + end.x) / 2 + 0.3f, start.y), direction, distance);
				objs[6] = rayDetect(new Vector2((start.x + end.x) / 2 + 0.6f, start.y), direction, distance);
			}
			
			return objs;
		}
		
		// 射线检测
		GameObject rayDetect(Vector2 start, Vector2 direction, float distance) {
			GameObject obj = null;
			RaycastHit2D hit = Physics2D.Raycast(start, direction, distance, 1 << LayerMask.NameToLayer("Default"));
			
			//Debug.DrawLine(new Vector3(start.x, start.y, 0), new Vector3(start.x, start.y + distance, 0), Color.red, 3f);
			
			if (hit.collider != null) {
				obj = hit.collider.gameObject;
			}
			
			return obj;
		}
		
		void autoRun(){
			float time = Time.time;
			if(time>state.preTime + SpeedCfg.inertiaTime){
				state.hasInertia = false;
				return;
			}
			if(state.direction == Common.LEFT){
				if (canMove(Common.LEFT)) {
					transform.position = new Vector3(pos.x - Time.deltaTime * state.speed, pos.y, pos.z);
				}
			}
			if(state.direction == Common.RIGHT){
				if (canMove(Common.RIGHT)) {
					transform.position = new Vector3(pos.x + Time.deltaTime * state.speed, pos.y, pos.z);
				}
			}
			
			if(state.direction == Common.UP){
				if (canMove(Common.UP)) {
					transform.position = new Vector3(pos.x, pos.y + Time.deltaTime * state.speed, pos.z);
				}
			}
			
			if(state.direction == Common.DOWN){
				if (canMove(Common.DOWN)) {
					transform.position = new Vector3(pos.x, pos.y - Time.deltaTime * state.speed, pos.z);
				}
			}
		}
		
		
		//----------------------------------摇杆操作
		
		void OnEnable() {
			EasyJoystick.On_JoystickMove += OnJoystickMove;
			EasyJoystick.On_JoystickMoveEnd += OnJoystickMoveEnd;
			
		}  
		
		void OnJoystickMoveEnd(MovingJoystick move) {
		}
		//移动摇杆中  
		
		void OnJoystickMove(MovingJoystick move) {
			//如果在本端没有控制权，就不进入
			if(move == null||state==null){
				return;
			}
			//死了就不能乱动了
			if (move.joystickName != "MoveJoystick" || !state.isAlive) {
				return;
			}
			//惯性让我漂移
			if(state.hasInertia){
				return;
			}
			
			//获取摇杆中心偏移的坐标
			float hX = move.joystickAxis.x;
			float hY = move.joystickAxis.y;
			
			hX = Mathf.Abs (hX)<Mathf.Abs (hY)?0:Mathf.Sign(hX);
			hY = Mathf.Abs (hX)>Mathf.Abs (hY)?0:Mathf.Sign(hY);
			
			if(hY==0){
				//转向
				
				//右移
				if(hX>0){
					if (canMove(Common.RIGHT*reverseFactor)) {
						transform.position = new Vector3(transform.position.x+hX*state.speed*Time.deltaTime*reverseFactor,transform.position.y,0.0f);
					}
					// 转向
					transform.rotation = Quaternion.Euler(new Vector3(0, 0, 270*reverseFactor));
					state.direction = Common.RIGHT*reverseFactor;	
				}
				//左移
				else if(hX<0){
					// 向左移动
					if (canMove(Common.LEFT*reverseFactor)) {
						transform.position = new Vector3(transform.position.x+hX*state.speed*Time.deltaTime*reverseFactor,transform.position.y,0.0f);
					}
					// 转向
					transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90*reverseFactor));
					state.direction = Common.LEFT*reverseFactor;
				}
			}
			else if(hX==0){
				if(hY>0){
					// 向上移动
					if (canMove(Common.UP*reverseFactor)) {
						transform.position = new Vector3(transform.position.x,transform.position.y+hY*state.speed*Time.deltaTime*reverseFactor,0.0f);
					}
					// 转向
					//!!! 角度逆时针为正
					float x = reverseFactor==-1?180:0;
					transform.rotation = Quaternion.Euler(new Vector3(0, 0,x));
					state.direction = Common.UP*reverseFactor;
				}
				//下移
				else if(hY<0){
					// 向下移动
					if (canMove(Common.DOWN*reverseFactor)) {
						transform.position = new Vector3(transform.position.x,transform.position.y+hY*state.speed*Time.deltaTime*reverseFactor,0.0f);
					}
					// 转向
					float x = reverseFactor==-1?0:180;
					transform.rotation = Quaternion.Euler(new Vector3(0, 0, x));
					state.direction = Common.DOWN*reverseFactor;
				}
			}
		}

		public void setReverseFactor(int x){
			this.reverseFactor = x;
		}

	}
}